<?php

namespace Crontab\Controller;

use Think\Controller;
use Think\Log;

/**
 * 促销活动刷价格，定时任务
 * Class DiscountController
 * @package Crontab\Controller
 */
class DiscountController extends Controller
{
    // log日志
    /**
     * @var string
     */
    private $logFile;

    /**
     * 构造函数
     * DiscountController constructor.
     */
    public function __construct()
    {
        $this->logFile = C('LOG_PATH') . 'Discount_' . date('y_m_d') . '.log';
    }

    /**
     * 添加折扣价到spec表，这是个定时任务
     */
    public function main()
    {
        // 逻辑
        // 循环ecm_goods_spec表中所有的数据, 判断是否有正在促销中的商品，具体条件为：
        // 1、有促销
        // 1）状态：启用
        // 2）时间：已经到了促销日期的
        // 3）促销活动包含goods_id、spec_id、storestock_id的
        // 2、无促销，如果无促销，discount_price和tax_discount_price都保持默认值0即可，不需要额外的操作

        // 设置脚本不过时
        set_time_limit(0);

        // 操作日志记录开始
        // 记录当前时间
        $date = date('Y-m-d H:i:s');
        $message = '现在正在记录spec表更改促销活动价格的操作，请知悉： ' . PHP_EOL;
        Log::write($message, 'debug', '', $this->logFile);

        // 首先取出相关model
        $goods_model = M('goods');
        $goods_spec_model = M('goods_spec');
        $coupon_codes_model = M('coupon_codes');
        $discount_model = M('discount');
        $my_tax_model = M('my_tax');
        $datas = $goods_spec_model->where('spec_id > 0')->select();
        // 开始循环判断
        foreach ($datas as $k => $data) {
            // 判断是否有优惠活动，我们规定一个sku, 一个发货仓只能参加一种促销活动
            // 如果没有优惠活动，那么就修改为默认价格
            if (empty($discount = $discount_model->where('spec_id = ' . $data['spec_id'] . ' AND goods_id = ' . $data['goods_id'] . ' AND storestock_id = ' . $data['spec_3value'])->find())) {
                $this->_removeDiscount($data['spec_id']);
                continue;
            }

            // 到这里说明优惠活动存在，但是该优惠券已经删除，说明优惠无效，那么价格也需要还原
            if (empty($coupon_codes = $coupon_codes_model->where('id = ' . $discount['coupon_codes_id'])->find())) {
                $this->_removeDiscount($data['spec_id']);
                continue;
            }

            // 到这里说明优惠券也存在，那么就判断该优惠券是否开启，并且是否在有效期之内，如果不满足的话，那么也需要价格还原
            if ($coupon_codes['enabled'] == '0' || $date < $coupon_codes['not_before'] || $date > $coupon_codes['not_after']) {
                $this->_removeDiscount($data['spec_id']);
                continue;
            }

            // 接下来就可以进行价格的修改了
            // 修改价格，需要知道税率id，这个要去goods表去查
            $goods = $goods_model->where('goods_id = ' . $data['goods_id'])->find();
            // 再去my_tax表去查税率的具体数值, 如果没查找默认为0.00
            $my_tax = $my_tax_model->where('tax_id = ' . $goods['tax_id'])->find();

            // 折扣值计算，分三种情况
            // 这里采用高精度计算
            switch ($coupon_codes['type']) {
                // 满减
                case '1':
                    $discount_price = bcsub($data['price'], $coupon_codes['value'], 2);
                    break;
                // 折扣
                case '2':
                    $discount_price = bcmul($data['price'], $coupon_codes['value'], 2);
                    break;
                // 自定义价格
                case '3':
                    $discount_price = $coupon_codes['value'];
                    break;
                // 默认为满减
                default:
                    $discount_price = bcsub($data['price'], $coupon_codes['value'], 2);
            }
            // 折扣价，同时价格做进位处理
            $discount_price = $this->changeNum($discount_price);
            $goods_spec_model->discount_price = $discount_price;
            // 优惠税钱 = 折扣价 * tax税率，折扣价是上面算好的价格
            $discount_consolidated_tax = $this->changeNum(bcmul($discount_price, $my_tax['consolidated_tax'], 2));
            $goods_spec_model->tax_discount_price = $discount_consolidated_tax;
            // 开始更新
            if ($goods_spec_model->where('spec_id=' . $data['spec_id'])->save() === false) {
                // 记录修改失败日志
                $message = 'spec表修改失败，当前操作的spec_id=' . $data['spec_id'] . PHP_EOL;
            } else {
                // 记录修改成功日志
                $message = 'spec表修改成功，当前操作的spec_id=' . $data['spec_id'] . ', 折扣价为：' . $discount_price . '，税率为：' . $my_tax['consolidated_tax'] . '，优惠税钱为：' . $discount_consolidated_tax . '。' . PHP_EOL;
            }
            // 记录日志
            Log::write($message, 'debug', '', $this->logFile);
        }

        // 记录操作完成日志
        $message = 'spec表更改促销活动价格处理完毕。 ' . PHP_EOL;
        Log::write($message, 'debug', '', $this->logFile);
    }

    /**
     * 数字补位
     * @param $number
     * @return float|string
     */
    public function changeNum($number)
    {
        // 逻辑
        // 具体处理规则
        // 如果数字尾数为6-9，则末尾变成0，前面一位进1
        $last = substr($number, -1);
        // 因为金额数值都是decimal，也就是整数和小数(两位)并存，那么
        if ($last >= 6 AND $last <= 9) {
            // 加0.1
            $number = bcadd($number, 0.1, 2);
            // 开始补位0，也可以理解为直接去掉最后一位
            $number = substr($number, 0, strlen($number) - 1) . '0';
        } else if ($last >= 1 AND $last <= 4) {
            // 开始补位5
            $number = substr($number, 0, strlen($number) - 1) . '5';
        }
        // 返回
        return $number;
    }

    /**
     * 去掉折扣价格，记录日志版本
     * @param int $spec_id sku_id
     */
    protected function _removeDiscount($spec_id)
    {
        // 如果找不到该sku的优惠，那么就修改为0
        $goods_spec_model = M('goods_spec');
        // 这其中，折扣价为0
        $goods_spec_model->discount_price = '0.00';
        // 优惠税率为0
        $goods_spec_model->tax_discount_price = '0.00';
        // 修改逻辑
        if ($goods_spec_model->where('spec_id=' . $spec_id)->save() === false) {
            // 记录日志
            $message = 'spec表税率及税费修改为0.00操作失败，当前操作的spec_id=' . $spec_id . PHP_EOL;
        } else {
            // 记录日志
            $message = 'spec表税率及税费修改为0.00操作成功，当前操作的spec_id=' . $spec_id . PHP_EOL;
        }
        // 记录
        // 记录日志
        Log::write($message, 'debug', '', $this->logFile);
    }
}